home *** CD-ROM | disk | FTP | other *** search
-
-
-
- oooovvvveeeerrrrllllooooaaaadddd((((3333)))) oooovvvveeeerrrrllllooooaaaadddd((((3333))))
-
-
-
- NNNNAAAAMMMMEEEE
- overload - Package for overloading perl operations
-
- SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
- package SomeThing;
-
- use overload
- '+' => \&myadd,
- '-' => \&mysub;
- # etc
- ...
-
- package main;
- $a = new SomeThing 57;
- $b=5+$a;
- ...
- if (overload::Overloaded $b) {...}
- ...
- $strval = overload::StrVal $b;
-
-
- CCCCAAAAVVVVEEEEAAAATTTT SSSSCCCCRRRRIIIIPPPPTTTTOOOORRRR
- Overloading of operators is a subject not to be taken lightly. Neither
- its precise implementation, syntax, nor semantics are 100% endorsed by
- Larry Wall. So any of these may be changed at some point in the future.
-
- DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
- DDDDeeeeccccllllaaaarrrraaaattttiiiioooonnnn ooooffff oooovvvveeeerrrrllllooooaaaaddddeeeedddd ffffuuuunnnnccccttttiiiioooonnnnssss
-
- The compilation directive
-
- package Number;
- use overload
- "+" => \&add,
- "*=" => "muas";
-
- declares function _N_u_m_b_e_r::_a_d_d() for addition, and method _m_u_a_s() in the
- "class" Number (or one of its base classes) for the assignment form *= of
- multiplication.
-
- Arguments of this directive come in (key, value) pairs. Legal values are
- values legal inside a &{ ... } call, so the name of a subroutine, a
- reference to a subroutine, or an anonymous subroutine will all work.
- Note that values specified as strings are interpreted as methods, not
- subroutines. Legal keys are listed below.
-
- The subroutine add will be called to execute $a+$b if $a is a reference
- to an object blessed into the package Number, or if $a is not an object
- from a package with defined mathemagic addition, but $b is a reference to
- a Number. It can also be called in other situations, like $a+=7, or
- $a++. See the section on _M_A_G_I_C _A_U_T_O_G_E_N_E_R_A_T_I_O_N. (Mathemagical methods
- refer to methods triggered by an overloaded mathematical operator.)
-
-
-
- PPPPaaaaggggeeee 1111
-
-
-
-
-
-
- oooovvvveeeerrrrllllooooaaaadddd((((3333)))) oooovvvveeeerrrrllllooooaaaadddd((((3333))))
-
-
-
- Since overloading respects inheritance via the @ISA hierarchy, the above
- declaration would also trigger overloading of + and *= in all the
- packages which inherit from Number.
-
- CCCCaaaalllllllliiiinnnngggg CCCCoooonnnnvvvveeeennnnttttiiiioooonnnnssss ffffoooorrrr BBBBiiiinnnnaaaarrrryyyy OOOOppppeeeerrrraaaattttiiiioooonnnnssss
-
- The functions specified in the use overload ... directive are called with
- three (in one particular case with four, see the section on _L_a_s_t _R_e_s_o_r_t)
- arguments. If the corresponding operation is binary, then the first two
- arguments are the two arguments of the operation. However, due to
- general object calling conventions, the first argument should always be
- an object in the package, so in the situation of 7+$a, the order of the
- arguments is interchanged. It probably does not matter when implementing
- the addition method, but whether the arguments are reversed is vital to
- the subtraction method. The method can query this information by
- examining the third argument, which can take three different values:
-
- FALSE the order of arguments is as in the current operation.
-
- TRUE the arguments are reversed.
-
- undef the current operation is an assignment variant (as in $a+=7), but
- the usual function is called instead. This additional information
- can be used to generate some optimizations.
-
- CCCCaaaalllllllliiiinnnngggg CCCCoooonnnnvvvveeeennnnttttiiiioooonnnnssss ffffoooorrrr UUUUnnnnaaaarrrryyyy OOOOppppeeeerrrraaaattttiiiioooonnnnssss
-
- Unary operation are considered binary operations with the second argument
- being undef. Thus the functions that overloads {"++"} is called with
- arguments ($a,undef,'') when $a++ is executed.
-
- OOOOvvvveeeerrrrllllooooaaaaddddaaaabbbblllleeee OOOOppppeeeerrrraaaattttiiiioooonnnnssss
-
- The following symbols can be specified in use overload:
-
- +o _A_r_i_t_h_m_e_t_i_c _o_p_e_r_a_t_i_o_n_s
-
- "+", "+=", "-", "-=", "*", "*=", "/", "/=", "%", "%=",
- "**", "**=", "<<", "<<=", ">>", ">>=", "x", "x=", ".", ".=",
-
- For these operations a substituted non-assignment variant can be
- called if the assignment variant is not available. Methods for
- operations "+", "-", "+=", and "-=" can be called to automatically
- generate increment and decrement methods. The operation "-" can be
- used to autogenerate missing methods for unary minus or abs.
-
- +o _C_o_m_p_a_r_i_s_o_n _o_p_e_r_a_t_i_o_n_s
-
- "<", "<=", ">", ">=", "==", "!=", "<=>",
- "lt", "le", "gt", "ge", "eq", "ne", "cmp",
-
- If the corresponding "spaceship" variant is available, it can be
-
-
-
- PPPPaaaaggggeeee 2222
-
-
-
-
-
-
- oooovvvveeeerrrrllllooooaaaadddd((((3333)))) oooovvvveeeerrrrllllooooaaaadddd((((3333))))
-
-
-
- used to substitute for the missing operation. During sorting
- arrays, cmp is used to compare values subject to use overload.
-
- +o _B_i_t _o_p_e_r_a_t_i_o_n_s
-
- "&", "^", "|", "neg", "!", "~",
-
- "neg" stands for unary minus. If the method for neg is not
- specified, it can be autogenerated using the method for subtraction.
- If the method for "!" is not specified, it can be autogenerated
- using the methods for "bool", or "\"\"", or "0+".
-
- +o _I_n_c_r_e_m_e_n_t _a_n_d _d_e_c_r_e_m_e_n_t
-
- "++", "--",
-
- If undefined, addition and subtraction methods can be used instead.
- These operations are called both in prefix and postfix form.
-
- +o _T_r_a_n_s_c_e_n_d_e_n_t_a_l _f_u_n_c_t_i_o_n_s
-
- "atan2", "cos", "sin", "exp", "abs", "log", "sqrt",
-
- If abs is unavailable, it can be autogenerated using methods for "<"
- or "<=>" combined with either unary minus or subtraction.
-
- +o _B_o_o_l_e_a_n, _s_t_r_i_n_g _a_n_d _n_u_m_e_r_i_c _c_o_n_v_e_r_s_i_o_n
-
- "bool", "\"\"", "0+",
-
- If one or two of these operations are unavailable, the remaining
- ones can be used instead. bool is used in the flow control
- operators (like while) and for the ternary "?:" operation. These
- functions can return any arbitrary Perl value. If the corresponding
- operation for this value is overloaded too, that operation will be
- called again with this value.
-
- +o _S_p_e_c_i_a_l
-
- "nomethod", "fallback", "=",
-
- see the section on _S_P_E_C_I_A_L _S_Y_M_B_O_L_S _F_O_R _u_s_e _o_v_e_r_l_o_a_d.
-
- See the section on _F_a_l_l_b_a_c_k for an explanation of when a missing method
- can be autogenerated.
-
- IIIInnnnhhhheeeerrrriiiittttaaaannnncccceeee aaaannnndddd oooovvvveeeerrrrllllooooaaaaddddiiiinnnngggg
-
- Inheritance interacts with overloading in two ways.
-
-
-
-
-
-
- PPPPaaaaggggeeee 3333
-
-
-
-
-
-
- oooovvvveeeerrrrllllooooaaaadddd((((3333)))) oooovvvveeeerrrrllllooooaaaadddd((((3333))))
-
-
-
- Strings as values of use overload directive
- If value in
-
- use overload key => value;
-
- is a string, it is interpreted as a method name.
-
- Overloading of an operation is inherited by derived classes
- Any class derived from an overloaded class is also overloaded. The
- set of overloaded methods is the union of overloaded methods of all
- the ancestors. If some method is overloaded in several ancestor,
- then which description will be used is decided by the usual
- inheritance rules:
-
- If A inherits from B and C (in this order), B overloads + with
- \&D::plus_sub, and C overloads + by "plus_meth", then the subroutine
- D::plus_sub will be called to implement operation + for an object in
- package A.
-
- Note that since the value of the fallback key is not a subroutine, its
- inheritance is not governed by the above rules. In the current
- implementation, the value of fallback in the first overloaded ancestor is
- used, but this is accidental and subject to change.
-
- SSSSPPPPEEEECCCCIIIIAAAALLLL SSSSYYYYMMMMBBBBOOOOLLLLSSSS FFFFOOOORRRR uuuusssseeee oooovvvveeeerrrrllllooooaaaadddd
- Three keys are recognized by Perl that are not covered by the above
- description.
-
- LLLLaaaasssstttt RRRReeeessssoooorrrrtttt
-
- "nomethod" should be followed by a reference to a function of four
- parameters. If defined, it is called when the overloading mechanism
- cannot find a method for some operation. The first three arguments of
- this function coincide with the arguments for the corresponding method if
- it were found, the fourth argument is the symbol corresponding to the
- missing method. If several methods are tried, the last one is used.
- Say, 1-$a can be equivalent to
-
- &nomethodMethod($a,1,1,"-")
-
- if the pair "nomethod" => "nomethodMethod" was specified in the use
- overload directive.
-
- If some operation cannot be resolved, and there is no function assigned
- to "nomethod", then an exception will be raised via _d_i_e()-- unless
- "fallback" was specified as a key in use overload directive.
-
- FFFFaaaallllllllbbbbaaaacccckkkk
-
- The key "fallback" governs what to do if a method for a particular
- operation is not found. Three different cases are possible depending on
- the value of "fallback":
-
-
-
- PPPPaaaaggggeeee 4444
-
-
-
-
-
-
- oooovvvveeeerrrrllllooooaaaadddd((((3333)))) oooovvvveeeerrrrllllooooaaaadddd((((3333))))
-
-
-
- +o undef Perl tries to use a substituted method (see the section
- on _M_A_G_I_C _A_U_T_O_G_E_N_E_R_A_T_I_O_N). If this fails, it then tries
- to calls "nomethod" value; if missing, an exception will
- be raised.
-
- +o TRUE The same as for the undef value, but no exception is
- raised. Instead, it silently reverts to what it would
- have done were there no use overload present.
-
- +o defined, but FALSE
- No autogeneration is tried. Perl tries to call
- "nomethod" value, and if this is missing, raises an
- exception.
-
- NNNNooootttteeee.... "fallback" inheritance via @ISA is not carved in stone yet, see the
- section on _I_n_h_e_r_i_t_a_n_c_e _a_n_d _o_v_e_r_l_o_a_d_i_n_g.
-
- CCCCooooppppyyyy CCCCoooonnnnssssttttrrrruuuuccccttttoooorrrr
-
- The value for "=" is a reference to a function with three arguments,
- i.e., it looks like the other values in use overload. However, it does
- not overload the Perl assignment operator. This would go against Camel
- hair.
-
- This operation is called in the situations when a mutator is applied to a
- reference that shares its object with some other reference, such as
-
- $a=$b;
- $a++;
-
- To make this change $a and not change $b, a copy of $$a is made, and $a
- is assigned a reference to this new object. This operation is done
- during execution of the $a++, and not during the assignment, (so before
- the increment $$a coincides with $$b). This is only done if ++ is
- expressed via a method for '++' or '+='. Note that if this operation is
- expressed via '+' a nonmutator, i.e., as in
-
- $a=$b;
- $a=$a+1;
-
- then $a does not reference a new copy of $$a, since $$a does not appear
- as lvalue when the above code is executed.
-
- If the copy constructor is required during the execution of some mutator,
- but a method for '=' was not specified, it can be autogenerated as a
- string copy if the object is a plain scalar.
-
- EEEExxxxaaaammmmpppplllleeee
- The actually executed code for
-
-
-
-
-
-
- PPPPaaaaggggeeee 5555
-
-
-
-
-
-
- oooovvvveeeerrrrllllooooaaaadddd((((3333)))) oooovvvveeeerrrrllllooooaaaadddd((((3333))))
-
-
-
- $a=$b;
- Something else which does not modify $a or $b....
- ++$a;
-
- may be
-
- $a=$b;
- Something else which does not modify $a or $b....
- $a = $a->clone(undef,"");
- $a->incr(undef,"");
-
- if $b was mathemagical, and '++' was overloaded with \&incr, '=' was
- overloaded with \&clone.
-
- MMMMAAAAGGGGIIIICCCC AAAAUUUUTTTTOOOOGGGGEEEENNNNEEEERRRRAAAATTTTIIIIOOOONNNN
- If a method for an operation is not found, and the value for "fallback"
- is TRUE or undefined, Perl tries to autogenerate a substitute method for
- the missing operation based on the defined operations. Autogenerated
- method substitutions are possible for the following operations:
-
- _A_s_s_i_g_n_m_e_n_t _f_o_r_m_s _o_f _a_r_i_t_h_m_e_t_i_c _o_p_e_r_a_t_i_o_n_s
- $a+=$b can use the method for "+" if the method for "+="
- is not defined.
-
- _C_o_n_v_e_r_s_i_o_n _o_p_e_r_a_t_i_o_n_s
- String, numeric, and boolean conversion are calculated in
- terms of one another if not all of them are defined.
-
- _I_n_c_r_e_m_e_n_t _a_n_d _d_e_c_r_e_m_e_n_t
- The ++$a operation can be expressed in terms of $a+=1 or
- $a+1, and $a-- in terms of $a-=1 and $a-1.
-
- abs($a) can be expressed in terms of $a<0 and -$a (or 0-$a).
-
- _U_n_a_r_y _m_i_n_u_s can be expressed in terms of subtraction.
-
- _N_e_g_a_t_i_o_n ! and not can be expressed in terms of boolean
- conversion, or string or numerical conversion.
-
- _C_o_n_c_a_t_e_n_a_t_i_o_n can be expressed in terms of string conversion.
-
- _C_o_m_p_a_r_i_s_o_n _o_p_e_r_a_t_i_o_n_s
- can be expressed in terms of its "spaceship" counterpart:
- either <=> or cmp:
-
- <, >, <=, >=, ==, != in terms of <=>
- lt, gt, le, ge, eq, ne in terms of cmp
-
-
- _C_o_p_y _o_p_e_r_a_t_o_r can be expressed in terms of an assignment to the
- dereferenced value, if this value is a scalar and not a
- reference.
-
-
-
- PPPPaaaaggggeeee 6666
-
-
-
-
-
-
- oooovvvveeeerrrrllllooooaaaadddd((((3333)))) oooovvvveeeerrrrllllooooaaaadddd((((3333))))
-
-
-
- WWWWAAAARRRRNNNNIIIINNNNGGGG
- The restriction for the comparison operation is that even if, for
- example, `cmp' should return a blessed reference, the autogenerated `lt'
- function will produce only a standard logical value based on the
- numerical value of the result of `cmp'. In particular, a working numeric
- conversion is needed in this case (possibly expressed in terms of other
- conversions).
-
- Similarly, .= and x= operators lose their mathemagical properties if the
- string conversion substitution is applied.
-
- When you _c_h_o_p() a mathemagical object it is promoted to a string and its
- mathemagical properties are lost. The same can happen with other
- operations as well.
-
- RRRRuuuunnnn----ttttiiiimmmmeeee OOOOvvvveeeerrrrllllooooaaaaddddiiiinnnngggg
- Since all use directives are executed at compile-time, the only way to
- change overloading during run-time is to
-
- eval 'use overload "+" => \&addmethod';
-
- You can also use
-
- eval 'no overload "+", "--", "<="';
-
- though the use of these constructs during run-time is questionable.
-
- PPPPuuuubbbblllliiiicccc ffffuuuunnnnccccttttiiiioooonnnnssss
- Package overload.pm provides the following public functions:
-
- overload::StrVal(arg)
- Gives string value of arg as in absence of stringify overloading.
-
- overload::Overloaded(arg)
- Returns true if arg is subject to overloading of some operations.
-
- overload::Method(obj,op)
- Returns undef or a reference to the method that implements op.
-
- IIIIMMMMPPPPLLLLEEEEMMMMEEEENNNNTTTTAAAATTTTIIIIOOOONNNN
- What follows is subject to change RSN.
-
- The table of methods for all operations is cached in magic for the symbol
- table hash for the package. The cache is invalidated during processing
- of use overload, no overload, new function definitions, and changes in
- @ISA. However, this invalidation remains unprocessed until the next
- blessing into the package. Hence if you want to change overloading
- structure dynamically, you'll need an additional (fake) blessing to
- update the table.
-
-
-
-
-
-
- PPPPaaaaggggeeee 7777
-
-
-
-
-
-
- oooovvvveeeerrrrllllooooaaaadddd((((3333)))) oooovvvveeeerrrrllllooooaaaadddd((((3333))))
-
-
-
- (Every SVish thing has a magic queue, and magic is an entry in that
- queue. This is how a single variable may participate in multiple forms
- of magic simultaneously. For instance, environment variables regularly
- have two forms at once: their %ENV magic and their taint magic. However,
- the magic which implements overloading is applied to the stashes, which
- are rarely used directly, thus should not slow down Perl.)
-
- If an object belongs to a package using overload, it carries a special
- flag. Thus the only speed penalty during arithmetic operations without
- overloading is the checking of this flag.
-
- In fact, if use overload is not present, there is almost no overhead for
- overloadable operations, so most programs should not suffer measurable
- performance penalties. A considerable effort was made to minimize the
- overhead when overload is used in some package, but the arguments in
- question do not belong to packages using overload. When in doubt, test
- your speed with use overload and without it. So far there have been no
- reports of substantial speed degradation if Perl is compiled with
- optimization turned on.
-
- There is no size penalty for data if overload is not used. The only size
- penalty if overload is used in some package is that _a_l_l the packages
- acquire a magic during the next blessing into the package. This magic is
- three-words-long for packages without overloading, and carries the cache
- tabel if the package is overloaded.
-
- Copying ($a=$b) is shallow; however, a one-level-deep copying is carried
- out before any operation that can imply an assignment to the object $a
- (or $b) refers to, like $a++. You can override this behavior by defining
- your own copy constructor (see the section on _C_o_p_y _C_o_n_s_t_r_u_c_t_o_r).
-
- It is expected that arguments to methods that are not explicitly supposed
- to be changed are constant (but this is not enforced).
-
- AAAAUUUUTTTTHHHHOOOORRRR
- Ilya Zakharevich <_i_l_y_a@_m_a_t_h._m_p_s._o_h_i_o-_s_t_a_t_e._e_d_u>.
-
- DDDDIIIIAAAAGGGGNNNNOOOOSSSSTTTTIIIICCCCSSSS
- When Perl is run with the ----DDDDoooo switch or its equivalent, overloading
- induces diagnostic messages.
-
- Using the m command of Perl debugger (see the _p_e_r_l_d_e_b_u_g manpage) one can
- deduce which operations are overloaded (and which ancestor triggers this
- overloading). Say, if eq is overloaded, then the method (eq is shown by
- debugger. The method () corresponds to the fallback key (in fact a
- presence of this method shows that this package has overloading enabled,
- and it is what is used by the Overloaded function).
-
- BBBBUUUUGGGGSSSS
- Because it is used for overloading, the per-package hash %OVERLOAD now
- has a special meaning in Perl. The symbol table is filled with names
- looking like line-noise.
-
-
-
- PPPPaaaaggggeeee 8888
-
-
-
-
-
-
- oooovvvveeeerrrrllllooooaaaadddd((((3333)))) oooovvvveeeerrrrllllooooaaaadddd((((3333))))
-
-
-
- For the purpose of inheritance every overloaded package behaves as if
- fallback is present (possibly undefined). This may create interesting
- effects if some package is not overloaded, but inherits from two
- overloaded packages.
-
- This document is confusing.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PPPPaaaaggggeeee 9999
-
-
-
-
-
-
- oooovvvveeeerrrrllllooooaaaadddd((((3333)))) oooovvvveeeerrrrllllooooaaaadddd((((3333))))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PPPPaaaaggggeeee 11110000
-
-
-
-
-
-
-